home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / Snippets / Devices / SCSI Simple Sample / Src / SCSISimpleSample.h < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-24  |  13.4 KB  |  472 lines  |  [TEXT/KAHL]

  1. /*                                SCSISimpleSample.h                                */
  2. /*
  3.  * SCSISimpleSample.h
  4.  * Copyright © 1992-94 Apple Computer Inc. All Rights Reserved.
  5.  */
  6. #ifdef REZ
  7. #define kApplicationCreator    '????'            /* Rez can't deal with long hex        */
  8. #else
  9. #define kApplicationCreator    0x3F3F3F3FL        /* '????' without trigraphs            */
  10. #endif
  11.  
  12. #define MBAR_MenuBar        1000
  13. #define MENU_Apple            1
  14. #define MENU_File            128
  15. #define MENU_Edit            129
  16. #define MENU_Test            130
  17. #define MENU_CurrentBus        131
  18. #define MENU_CurrentTarget    132
  19. #define MENU_CurrentLUN        133
  20. #define STRS_SenseBase        1000
  21. #define DLOG_About            128
  22.  
  23. #define kMinWindowWidth        200
  24. #define kMinWindowHeight    300
  25. #define kLogLines            512
  26.  
  27. #ifndef REZ
  28. /*
  29.  * These definitions are only for the code files.
  30.  */
  31. #ifndef THINK_C                /* MPW includes            */
  32. #include <Errors.h>
  33. #include <Script.h>
  34. #include <Types.h>
  35. #include <Resources.h>
  36. #include <QuickDraw.h>
  37. #include <Fonts.h>
  38. #include <Events.h>
  39. #include <Windows.h>
  40. #include <ToolUtils.h>
  41. #include <Memory.h>
  42. #include <Menus.h>
  43. #include <Lists.h>
  44. #include <Printing.h>
  45. #include <Dialogs.h>
  46. #include <Packages.h>
  47. #endif
  48.  
  49. #ifndef TRUE
  50. #define TRUE    1
  51. #define FALSE    0
  52. #endif
  53. #ifndef EXTERN
  54. #define EXTERN    extern
  55. #endif
  56.  
  57. #include "MacSCSICommand.h"
  58. #include "LogManager.h"
  59.  
  60. #define kScrollBarWidth        16
  61. #define kScrollBarOffset    (kScrollBarWidth - 1)
  62.  
  63. /*
  64.  * Items in the Apple Menu
  65.  */
  66. enum {
  67.     kAppleAbout = 1
  68. };
  69.  
  70. /*
  71.  * Items in the File Menu
  72.  */
  73. enum {
  74.     kFileCreateLogFile = 1,
  75.     kFileCloseLogFile,
  76.     kFileUnused1,
  77.     kFilePageSetup,
  78.     kFilePrint,
  79.     kFileUnused2,
  80.     kFileDebug,
  81.     kFileUnused3,
  82.     kFileQuit
  83. };
  84.  
  85. enum EditMenu {
  86.     kEditUndo                = 1,
  87.     kEditUnused,
  88.     kEditCut,
  89.     kEditCopy,
  90.     kEditPaste,
  91.     kEditClear
  92. };
  93.  
  94. /*
  95.  * Items in the test Menu
  96.  */
  97. enum {
  98.     kTestEnableNewManager = 1,
  99.     kTestEnableAllLogicalUnits,
  100.     kTestEnableSelectWithATN,
  101.     kTestUnused1,
  102.     kTestDoDisconnect,
  103.     kTestDontDisconnect,
  104.     kTestUnused2,
  105.     kTestListSCSIDevices,
  106.     kTestGetDriveInfo,
  107.     kTestUnitReady,
  108.     kTestReadBlockZero,
  109.     kTestUnused3,
  110.     kTestVerboseDisplay,
  111.     kTestDummyLastEntryThankYouANSICCommittee
  112. };
  113.  
  114. /*
  115.  * This is a parameter block for DoSCSICommandWithSense that contains all of the
  116.  * data needed to perform a SCSI command on either the original or asynchronous
  117.  * SCSI Managers. Note: some of this is used only by one or the other manager.
  118.  */
  119. struct ScsiCmdBlock {
  120.     DeviceIdent            scsiDevice;                /* -> Bus/target/LUN    */
  121.     Ptr                    bufferPtr;                /* -> data buffer        */
  122.     unsigned long        transferSize;            /* -> bytes to transfer    */
  123.     unsigned long        transferQuantum;        /* -> TIB count            */
  124.     unsigned short        statusByte;                /* <- From Status Phase    */
  125.     unsigned short        messageByte;            /* <- From Msg Phase    */
  126.     unsigned long        actualTransferCount;    /* <- Transfer count    */
  127.     Boolean                writeToDevice;            /* -> Need data out?    */
  128.     unsigned long        scsiFlags;                /* -> asynch flags        */
  129.     OSErr                status;                    /* <- Current OSErr        */
  130.     OSErr                requestSenseStatus;        /* <- From RequestSense    */
  131.     SCSI_Command        command;                /* -> Current command    */
  132.     SCSI_Sense_Data        sense;                    /* <- Gets Sense data    */
  133. };
  134. typedef struct ScsiCmdBlock ScsiCmdBlock, *ScsiCmdBlockPtr;
  135. /*
  136.  * Notes on the above:
  137.  *    scsiDevice            Used for both managers, but the original manager
  138.  *                        ignores the bus and LUN designations. The caller
  139.  *                        must stuff the LUN into the command data block.
  140.  *    bufferPtr            If NULL, no read/write is performed.
  141.  *    transferSize        If zero, no read/write is performed.
  142.  *    transferQuantum        This is used by the handshake and TIB setup. Note:
  143.  *                        we support only the simplest "512, 0" handshake
  144.  *                        and TIB. The following values are useful:
  145.  *                            0        transferQuantum := transferSize
  146.  *                            1        force polled read/write
  147.  *                            > 1        blocked read (for example, 512)
  148.  *    statusByte            Returned from the device
  149.  *    messageByte            Returned from the device (Command Complete)
  150.  *    actualTransfercount Returned in bytes (transferQuantum sets granularity)
  151.  *    scsiFlags            Set special flags (scsiDontDisconnect) here.
  152.  *    status                Overall operation status (note special status values)
  153.  *    requestSenseStatus    Has status of Request Sense (only if status was
  154.  *                        statusErr, indicating that "Check condition" status.
  155.  */
  156.     
  157. /*
  158.  * These are the things the user can choose from the menu:
  159.  *    ListSCSIDevices                Scan all busses and display info for all
  160.  *                                devices (all targets, all LUNs)
  161.  *    DeviceInquiry                Execute an Inquiry command for this device
  162.  *                                and display the results.
  163.  *    TestUnitReady                Execute a Test Unit Ready command for this
  164.  *                                device and display the results.
  165.  */
  166. void                        DoListSCSIDevices(void);
  167. void                        DoGetDriveInfo(
  168.         DeviceIdent                scsiDevice,                /* -> Bus/target/LUN    */
  169.         Boolean                    noIntroMsg
  170.     );
  171. void                        DoTestUnitReady(
  172.         DeviceIdent                scsiDevice                /* -> Bus/target/LUN    */
  173.     );
  174. void                        DoReadBlockZero(
  175.         DeviceIdent                scsiDevice                /* -> Bus/target/LUN    */
  176.     );
  177. /*
  178.  * These are low-level commands that are needed to scan the bus.
  179.  */
  180. Boolean                        SCSICheckForDevicePresent(
  181.         DeviceIdent                scsiDevice,
  182.         Boolean                    enableAsynchSCSI
  183.     );
  184. /*
  185.  * Return the number of SCSI busses on this system.
  186.  */
  187. OSErr                        SCSIGetHighHostBusAdaptor(
  188.         unsigned short            *lastHostBus
  189.     );
  190. /*
  191.  * Return the SCSI bus ID of the initiator (Macintosh) on this bus. This will
  192.  * normally return 7. It always returns 7 if the asynchronous SCSI Manager is
  193.  * not present on this machine. Errors are serious.
  194.  */ 
  195. OSErr                        SCSIGetInitiatorID(
  196.         DeviceIdent                scsiDevice,
  197.         unsigned short            *initiatorID
  198.     );
  199. /*
  200.  * TRUE if the asynchronous SCSI Manager is running on this machine.
  201.  */
  202. Boolean                        AsyncSCSIPresent(void);
  203.  
  204. /*
  205.  * All commands are performed by this function. If the asynchronous SCSI Manager
  206.  * is present, it is called directly. If it is not present, the original SCSI
  207.  * Manager is called and, if the device returns Check Condition, a Request
  208.  * Sense command is issued.
  209.  */
  210. void                        DoSCSICommandWithSense(
  211.         register ScsiCmdBlockPtr    scsiCmdBlockPtr,
  212.         Boolean                    displayError,
  213.         Boolean                    enableAsynchSCSI
  214.     );
  215.  
  216. /*
  217.  * The following functions display operation results.
  218.  */
  219. void                        ShowSCSIBusID(
  220.         DeviceIdent                scsiDevice,                /* -> Bus/target/LUN    */
  221.         ConstStr255Param        commandText
  222.     );
  223. void                        ShowRequestSense(
  224.         register ScsiCmdBlockPtr    scsiCmdBlockPtr
  225.     );
  226. /*
  227.  * This does the actual formatting and display of the Request Sense results
  228.  */
  229. void                        DoShowRequestSense(
  230.         DeviceIdent                scsiDevice,
  231.         OSErr                    operationStatus,
  232.         OSErr                    requestSenseStatus,
  233.         const SCSI_CommandPtr    scsiCommand,
  234.         const SCSI_Sense_Data    *sensePtr
  235.     );
  236. void                        ShowStatusError(
  237.         DeviceIdent                scsiDevice,                /* -> Bus/target/LUN    */
  238.         OSErr                    errorStatus,
  239.         const SCSI_CommandPtr    scsiCommand
  240.     );
  241. void                        DoShowSCSICommand(
  242.         const SCSI_CommandPtr    cmdBlock,            /* -> SCSI command            */
  243.         ConstStr255Param        message
  244.     );
  245. /*
  246.  * The inquiry data is stored in SCB.bufferPtr
  247.  */
  248. void                        ShowInquiry(
  249.         register ScsiCmdBlockPtr    scsiCmdBlockPtr
  250.     );
  251. void                        DoShowInquiry(
  252.         DeviceIdent                scsiDevice,                /* -> Bus/target/LUN    */
  253.         const SCSI_Inquiry_Data    *inquiry
  254.     );
  255. void                        ShowDeviceState(
  256.         register ScsiCmdBlockPtr    scsiCmdBlockPtr
  257.     );
  258. void                        AppendDeviceID(
  259.         StringPtr                result,
  260.         DeviceIdent                scsiDevice                /* -> Bus/target/LUN    */
  261.     );
  262. void                        DisplaySCSIErrorMessage(
  263.         OSErr                    errorStatus,
  264.         ConstStr255Param        errorText
  265.     );
  266. /*
  267.  * Use the SCSI-II command class to determine the command length. Returns
  268.  * zero if the length could not be determined.
  269.  */
  270. unsigned short                SCSIGetCommandLength(
  271.         const Ptr                cmdBlock
  272.     );
  273. /*
  274.  * These two functions are called by DoSCSICommandWithSense to perform the
  275.  * actual operation. OriginalSCSI uses the Inside Mac IV SCSI Manager, while
  276.  * AsyncSCSI uses SCSI Manager 4.3.
  277.  * Return codes:
  278.  *
  279.  *    noErr            normal
  280.  *    unimpErr        AsyncSCSI called, but SCSI Manager 4.3 not installed.
  281.  *    scCommErr        Could not select this device or bus busy (Original only)
  282.  *    statusErr        Device returned "Check condition"
  283.  *    controlErr        Device returned "Busy" (Note: device error)
  284.  *    ioErr            Other (serious) device status -- bug.
  285.  *    sc...            Other (Inside Mac IV) SCSI Manager error
  286.  *    scsi...            Other (SCSI Manager 4.3) error.
  287.  */
  288. OSErr                        OriginalSCSI(
  289.         unsigned short            targetID,            /* Device ID on this bus    */
  290.         const SCSI_CommandPtr    scsiCommand,        /* The actual scsi command    */
  291.         unsigned short            cmdBlockLength,        /* -> Length of CDB            */
  292.         Boolean                    writeToDevice,        /* TRUE to write            */
  293.         Ptr                        bufferPtr,            /* -> user data buffer        */
  294.         unsigned long            transferSize,        /* How much to transfer        */
  295.         unsigned long            transferQuantum,    /* TIB setup parameter        */
  296.         unsigned long            completionTimeout,    /* Ticks to wait            */
  297.         unsigned short            *stsBytePtr,        /* <- status phase byte        */
  298.         unsigned short            *msgBytePtr,        /* <- cmd complete messge    */
  299.         unsigned long            *actualTransferCount
  300.     );
  301. /*
  302.  * AsyncSCSI returns unimpErr if the _SCSIAtomic (SCSI Manager 4.3)
  303.  * trap is not present. If so, just call the "old" OriginalSCSI.
  304.  */
  305. OSErr                        AsyncSCSI(
  306.         DeviceIdent                scsiDevice,            /* -> Bus/target/LUN        */
  307.         const SCSI_CommandPtr    scsiCommand,        /* The actual scsi command    */
  308.         unsigned short            cmdBlockLength,        /* -> Length of CDB            */
  309.         Boolean                    writeToDevice,        /* TRUE to write            */
  310.         Ptr                        bufferPtr,            /* -> user data buffer        */
  311.         unsigned long            transferSize,        /* How much to transfer        */
  312.         unsigned long            transferQuantum,    /* TIB setup parameter        */
  313.         SCSI_Sense_Data            *senseDataPtr,        /* Request Sense results    */
  314.         unsigned long            senseDataSize,        /* Request Sense data size    */
  315.         unsigned long            completionTimeout,    /* Ticks to wait            */
  316.         unsigned short            *stsBytePtr,        /* <- status phase byte        */
  317.         unsigned short            *msgBytePtr,        /* <- cmd complete messge    */
  318.         unsigned long            *actualTransferCount
  319.     );
  320.  
  321. /*
  322.  * String formatting utilities (for debugging/display)
  323.  */
  324. /*
  325.  * AppendChar writes a character into the string. Note that
  326.  * it wraps around if the string size exceeds 255 bytes.
  327.  */
  328. #define AppendChar(result, c) (result[++result[0]] = (c))
  329. void                        AppendUnsigned(
  330.         StringPtr                result,
  331.         unsigned long            value
  332.     );
  333. void                        AppendSigned(
  334.         StringPtr                result,
  335.         signed long                value
  336.     );
  337. void                        AppendUnsignedLeadingZeros(
  338.         StringPtr                result,
  339.         unsigned long            value,
  340.         short                    fieldWidth,
  341.         short                    terminatorChar
  342.     );
  343. void                        AppendHexLeadingZeros(
  344.         StringPtr                result,
  345.         unsigned long            value,
  346.         short                    fieldWidth
  347.     );
  348. void                        AppendUnsignedInField(
  349.         StringPtr                result,
  350.         unsigned long            value,
  351.         short                    fieldWidth
  352.     );
  353. void                        AppendBytes(
  354.         StringPtr                result,
  355.         const Ptr                source,
  356.         unsigned short            length
  357.     );
  358. void                        AppendPascalString(
  359.         StringPtr                result,
  360.         const StringPtr            value
  361.     );
  362. void                        AppendCString(
  363.         StringPtr                result,
  364.         const char                *source,
  365.         unsigned short            maxLength        /* Ignored if zero    */
  366.     );
  367. void                        AppendOSType(
  368.         StringPtr                result,
  369.         OSType                    value
  370.     );
  371. /*
  372.  * Window Utilities
  373.  */
  374. void                        DoZoomWindow(
  375.         WindowPtr                theWindow,
  376.         short                    whichPart
  377.     );
  378. Boolean                        DoGrowWindow(
  379.         WindowPtr                theWindow,
  380.         Point                    eventWhere,
  381.         short                    minimumWidth,
  382.         short                    minimumHeight
  383.     );
  384. void                        MyDrawGrowIcon(
  385.         WindowPtr                theWindow
  386.     );
  387.  
  388. /*
  389.  * Format a block of data into the log.
  390.  */
  391. void                        DisplayDataBlock(
  392.         Ptr                        dataPtr,
  393.         unsigned short            dataLength
  394.     );
  395. /*
  396.  * Cheap 'n dirty pascal string copy routine.
  397.  */
  398. #define pstrcpy(dst, src) do {                            \
  399.         StringPtr    _src = (StringPtr) (src);            \
  400.         BlockMove(_src, dst, _src[0] + 1);                \
  401.     } while (0)
  402. /*
  403.  * Cheap 'n dirty pascal string concat.
  404.  */
  405. #define pstrcat(dst, src) do {                            \
  406.         StringPtr        _dst = (dst);                    \
  407.         StringPtr        _src = (StringPtr) (src);        \
  408.         short            _len;                            \
  409.         _len = 255 - _dst[0];                            \
  410.         if (_len > _src[0]) _len = _src[0];                \
  411.         BlockMove(&_src[1], &_dst[1] + _dst[0], _len);    \
  412.         _dst[0] += _len;                                \
  413.     } while (0)
  414.  
  415. /*
  416.  * Cheap 'n dirty memory clear routine.
  417.  */
  418. #define CLEAR(record) do {                                \
  419.         register char    *ptr = (char *) &record;        \
  420.         register long    size;                            \
  421.         for (size = sizeof record; size > 0; --size)    \
  422.             *ptr++ = 0;                                    \
  423.     } while (0)
  424.  
  425. #define width(r)    ((r).right - (r).left)
  426. #define height(r)    ((r).bottom - (r).top)
  427.  
  428. #define LOG(what)    DisplayLogString(gLogListHandle, (what))
  429. #define VERBOSE(what) do {                                \
  430.         if (gVerboseDisplay)                            \
  431.             LOG(what);                                    \
  432.     } while (0)
  433. /*
  434.  * Global variables.
  435.  */
  436. EXTERN WindowPtr                gMainWindow;
  437. EXTERN EventRecord                gCurrentEvent;
  438. #define EVENT                    (gCurrentEvent)
  439. EXTERN ListHandle                gLogListHandle;
  440. EXTERN THPrint                    gPrintHandle;
  441. EXTERN Boolean                    gQuitNow;
  442. EXTERN Boolean                    gUpdateMenusNeeded;
  443. EXTERN Boolean                    gInForeground;
  444. /*
  445.  * These flags are set/cleared by menu options to control the asynchronous SCSI
  446.  * Manager -- they are not used if the asynchronous manager is not present.
  447.  *    gEnableNewSCSIManager        FALSE to always use the original manager,
  448.  *                                even if the new manager is present.
  449.  *    gEnableSelectWithATN        FALSE to supress Select With ATN.
  450.  *    gDoDisconnect                Set the scsibDoDisconnect flag
  451.  *    gDontDisconnect                Set the scsibDontDisconnect flag.
  452.  *                                Note: both "do" and "don't" may be set.
  453.  */
  454. EXTERN Boolean                    gEnableNewSCSIManager;
  455. EXTERN Boolean                    gEnableSelectWithATN;
  456. EXTERN Boolean                    gDoDisconnect;
  457. EXTERN Boolean                    gDontDisconnect;
  458. EXTERN Boolean                    gVerboseDisplay;
  459. EXTERN MenuHandle                gAppleMenu;
  460. EXTERN MenuHandle                gFileMenu;
  461. EXTERN MenuHandle                gEditMenu;
  462. EXTERN MenuHandle                gTestMenu;
  463. EXTERN MenuHandle                gCurrentBusMenu;
  464. EXTERN MenuHandle                gCurrentTargetMenu;
  465. EXTERN MenuHandle                gCurrentLUNMenu;
  466. EXTERN DeviceIdent                gCurrentDevice;
  467. EXTERN unsigned short            gMaxLogicalUnit;
  468. EXTERN DeviceIdent                *gDeviceList;
  469. EXTERN unsigned short            gMaxDevice;        /* Number of items in gDeviceList    */
  470.  
  471. #endif        /* REZ            */
  472.